package net.zigin.nhi.could.waste.service.impl;

import net.zigin.commons.util.AssertUtil;
import net.zigin.commons.util.ParamsMapUtil;
import net.zigin.commons.util.ReflectUtil;
import net.zigin.commons.util.StringUtil;
import net.zigin.nhi.could.waste.aop.LoginAspect;
import net.zigin.nhi.could.waste.dao.*;
import net.zigin.nhi.could.waste.model.*;
import net.zigin.nhi.could.waste.vo.TokenInfoBo;
import net.zigin.nhi.could.waste.constants.CommonConstants;
import net.zigin.nhi.could.waste.dto.HospitalBaseDto;
import net.zigin.nhi.could.waste.service.SysRoleService;
import net.zigin.nhi.could.waste.service.SysUserService;
import net.zigin.nhi.could.waste.util.HttpClientUtil;
import net.zigin.nhi.could.waste.util.SecurityUtil;
import net.zigin.nhi.could.waste.vo.HospitalBaseVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import net.zigin.nhi.could.waste.service.HospitalBaseService;

import java.util.*;

/*#################################################################*
# 说明:以下代码通过哲勤代码生成工具自动生成    
# 工具:GeneratorCode
# 作者:mgw1986                                                  
# 生成时间:2021-9-8 0:01:00
##################################################################*/


/**
 * HospitalBase服务实现类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: HospitalBaseServiceImpl
 * @date 2021-9-8 0:01:00
 */
@Service
public class HospitalBaseServiceImpl extends AbstractServiceImpl<HospitalBase, String> implements HospitalBaseService {
    @Autowired
    private HospitalBaseMapper hospitalBaseMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserHospitalMapper sysUserHospitalMapper;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private WarnTimeMapper warnTimeMapper;
    @Autowired
    private WarnWeightMapper warnWeightMapper;
    @Autowired
    private SysDictionMapper sysDictionMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Value("${zigin.customSmsUrl}")
    private String customSmsUrl;

    @Override
    public BaseMapper<HospitalBase, String> getMapper() {
        return hospitalBaseMapper;
    }


    @Override
    public String saveOrUpdate(HospitalBaseDto hospitalBaseDto) {
        AssertUtil.isNull(hospitalBaseDto, "医院信息不能为空");
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        if (StringUtil.isNullOrEmpty(hospitalBaseDto.getId())) {
            AssertUtil.isNull(hospitalBaseDto.getName(), "医院名称不能为空");
            AssertUtil.isNull(hospitalBaseDto.getCreditCode(), "信用代码不能为空");
            AssertUtil.isNull(hospitalBaseDto.getAdminName(), "管理员姓名不能为空");
            AssertUtil.isNull(hospitalBaseDto.getAdminMobile(), "管理员电话不能为空");
            AssertUtil.isNull(hospitalBaseDto.getAddress(), "地址不能为空");
            sysUserService.checkMobileExist(hospitalBaseDto.getAdminMobile());
            hospitalBaseDto.setId(StringUtil.get32UUID());
            hospitalBaseDto.setCreateTime(new Date());
            hospitalBaseDto.setModifyTime(new Date());
            hospitalBaseDto.setCreditStatus("success");
            hospitalBaseDto.setCreateUser(tokenInfo.getLoginName());
            HospitalBase hospitalBase = ReflectUtil.copyProperties(hospitalBaseDto, HospitalBase.class);
            hospitalBase.setNum(generateCode());
            hospitalBaseMapper.insert(hospitalBase);
            // todo 创建 user(name,mobile)  user_hospital(name) 校验手机号唯一
            SysUser sysUser = new SysUser(hospitalBaseDto);
            sysUserMapper.insert(sysUser);
            // 创建医院管理员角色 绑定菜单 绑定角色
            //String roleId = initHospitalAdminRole(hospitalBase.getId());
            sysRoleService.concatUser(sysUser.getId(), 0);
            //sysRoleService.concatUser(Collections.singletonList(roleId), sysUser.getId());
            SysUserHospital userHospital = new SysUserHospital(hospitalBaseDto);
            userHospital.setSysUserId(sysUser.getId());
            userHospital.setHospitalBaseId(hospitalBase.getId());
            sysUserHospitalMapper.insert(userHospital);
            // todo 初始化预警规则
            initWarnRule(hospitalBase.getId());
            return hospitalBase.getId();
        }
        // 禁用
        if (hospitalBaseDto.getIsFreeze() == 1) {
            hospitalBaseDto.setFreezeTime(new Date());
        }
        // 修改管理员信息
        if (!StringUtil.isNullOrEmpty(hospitalBaseDto.getAdminId()) && !StringUtil.isNullOrEmpty(hospitalBaseDto.getAdminName()) && !StringUtil.isNullOrEmpty(hospitalBaseDto.getAdminName())) {
            SysUser sysUser = sysUserMapper.selectByPrimaryKey(hospitalBaseDto.getAdminId());
            if (!sysUser.getName().equals(hospitalBaseDto.getAdminName()) || !sysUser.getMobile().equals(hospitalBaseDto.getAdminMobile())) {
                sysUser.setName(hospitalBaseDto.getAdminMobile());
                sysUser.setMobile(hospitalBaseDto.getAdminMobile());
                sysUserMapper.updateByPrimaryKeySelective(sysUser);
            }
        }
        // sysUserHospitalMapper.getBySysUserId(hospitalBaseDto.getAdminId()); 忘了有啥用 先不删
        // 认证后 发送短信
        if (!StringUtil.isNullOrEmpty(hospitalBaseDto.getCreditStatus()) && !hospitalBaseDto.getCreditStatus().equals(CommonConstants.CREDIT_WAIT)) {
            String smsContent = "【医废追溯系统】您的注册申请";
            if (hospitalBaseDto.getCreditStatus().equals(CommonConstants.CREDIT_SUCCESS)) {
                smsContent += "已通过审核，请通过当前注册账号登录系统。";
            } else if (hospitalBaseDto.getCreditStatus().equals(CommonConstants.CREDIT_FAIL)) {
                smsContent += "未通过审核，您可完善相关资料并重新提交申请";
                // todo 拒绝后 删除账号
                removeUser(hospitalBaseDto.getAdminMobile());
            }
            HttpClientUtil.smsCustomCode(customSmsUrl, hospitalBaseDto.getAdminMobile(), smsContent);
        }
        hospitalBaseDto.setModifyTime(new Date());
        hospitalBaseDto.setModifyUser(tokenInfo.getLoginName());
        HospitalBase hospitalBase = ReflectUtil.copyProperties(hospitalBaseDto, HospitalBase.class);
        hospitalBaseMapper.updateByPrimaryKeySelective(hospitalBase);
        return hospitalBase.getId();
    }

    private String initHospitalAdminRole(String hospitalBaseId) {
        SysRole sysRole = new SysRole(hospitalBaseId);
        sysRoleMapper.insert(sysRole);
        // 绑定菜单
        String roleId = sysRoleMapper.getIdByCode("h1001");
        List<String> menuIdsByRoleId = sysRoleMapper.getMenuIdsByRoleId(roleId);
        sysRoleService.concatMenu(sysRole.getId(), menuIdsByRoleId);
        return sysRole.getId();
    }

    private Map<String, Object> getHospitalBaseParam(HospitalBaseDto hospitalBaseDto) {
        return ParamsMapUtil.getInstance()
                .addParam("name", hospitalBaseDto.getName())
                .addParam("code", hospitalBaseDto.getCode())
                .addParam("showAll", hospitalBaseDto.getShowAll())
                .addParam("creditStatus", hospitalBaseDto.getCreditStatus())
                .addParam("creditCode", hospitalBaseDto.getCreditCode())
                .addParam("address", hospitalBaseDto.getAddress())
                .addParam("adminName", hospitalBaseDto.getAdminName())
                .addParam("adminMobile", hospitalBaseDto.getAdminMobile())
                .addParam("ifFreeze", hospitalBaseDto.getIsFreeze())
                .addParam("ifFreeze", hospitalBaseDto.getProvinceCode())
                .addParam("ifFreeze", hospitalBaseDto.getCityCode())
                .addParam("ifFreeze", hospitalBaseDto.getRegionCode())
                .addParam("ifFreeze", hospitalBaseDto.getTownCode())
                .addParam("pageSize", hospitalBaseDto.getPageSize())
                .addParam("pageIndex", hospitalBaseDto.getPageIndex());
    }

    @Override
    public List<HospitalBaseVo> getList(HospitalBaseDto hospitalBaseDto) {
        Map<String, Object> paramMap = getHospitalBaseParam(hospitalBaseDto);
        List<HospitalBase> hospitalBases = hospitalBaseMapper.selectListByPage(paramMap);
        if (hospitalBases.isEmpty()) {
            return new ArrayList<>();
        }
        List<HospitalBaseVo> hospitalBaseVos = ReflectUtil.copyProperties(hospitalBases, HospitalBaseVo.class);
        hospitalBaseVos.forEach(hospitalBaseVo -> {
            hospitalBaseVo.setAdminId(sysUserHospitalMapper.getSysUserIdByHospitalBaseId(hospitalBaseVo.getId()));
        });
        return hospitalBaseVos;
    }

    @Override
    public Integer getCount(HospitalBaseDto hospitalBaseDto) {
        Map<String, Object> paramMap = getHospitalBaseParam(hospitalBaseDto);
        return hospitalBaseMapper.selectCount(paramMap);
    }

    @Override
    public String register(HospitalBaseDto hospitalBaseDto) {
        //TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        AssertUtil.isNull(hospitalBaseDto.getName(), "医院名称不能为空");
        AssertUtil.isNull(hospitalBaseDto.getCreditCode(), "信用代码不能为空");
        AssertUtil.isNull(hospitalBaseDto.getAdminName(), "管理员姓名不能为空");
        AssertUtil.isNull(hospitalBaseDto.getAdminMobile(), "管理员电话不能为空");
        AssertUtil.isNull(hospitalBaseDto.getAddress(), "地址不能为空");
        sysUserService.checkMobileExist(hospitalBaseDto.getAdminMobile());
        hospitalBaseDto.setId(StringUtil.get32UUID());
        hospitalBaseDto.setCreateTime(new Date());
        hospitalBaseDto.setModifyTime(new Date());
        hospitalBaseDto.setCreditStatus("wait");
        //hospitalBaseDto.setCreateUser(tokenInfo.getLoginName());
        HospitalBase hospitalBase = ReflectUtil.copyProperties(hospitalBaseDto, HospitalBase.class);
        hospitalBase.setNum(generateCode());
        hospitalBaseMapper.insert(hospitalBase);
        // todo 创建 user(name,mobile)  user_hospital(name) 校验手机号唯一
        SysUser sysUser = new SysUser(hospitalBaseDto);
        sysUser.setPassword(SecurityUtil.encodePassword(hospitalBaseDto.getPassword()));
        sysUserMapper.insert(sysUser);
        SysUserHospital userHospital = new SysUserHospital(hospitalBaseDto);
        userHospital.setSysUserId(sysUser.getId());
        userHospital.setHospitalBaseId(hospitalBase.getId());
        sysUserHospitalMapper.insert(userHospital);
        // 初始化规则
        initWarnRule(hospitalBase.getId());
        // 绑定基础角色 h001
        //String roleId = initHospitalAdminRole(hospitalBase.getId());
        sysRoleService.concatUser(userHospital.getSysUserId(), 0);
        //sysRoleService.concatUser(Collections.singletonList(roleId), sysUser.getId());
        return hospitalBase.getId();
    }

    @Override
    public void deleteById(String id) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String loginName = tokenInfo.getLoginName();
        // 查询待删除医院记录
        HospitalBase hospitalBase = hospitalBaseMapper.selectByPrimaryKey(id);
        AssertUtil.isNull(hospitalBase,"待删除的医院记录不存在");
        AssertUtil.isNull(hospitalBase.getIsFreeze() != 1,"待删除的医院记录必须为禁用状态");
        // 获取用户id 更新该用户为删除状态
        String sysUserId = sysUserHospitalMapper.getSysUserIdByHospitalBaseId(id);
        SysUser sysUser = new SysUser();
        sysUser.setId(sysUserId);
        sysUser.setIsDelete(1);
        sysUser.setDeleteTime(new Date());
        sysUser.setModifyUser(loginName);
        sysUser.setModifyTime(new Date());
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        hospitalBaseMapper.deleteByPrimaryKey(id);
    }

    private void initWarnRule(String hospitalBaseId) {
        WarnTime warnTime = new WarnTime(hospitalBaseId);
        warnTimeMapper.insert(warnTime);
        List<SysDiction> sysDictions = sysDictionMapper.selectListByCondition(ParamsMapUtil.getInstance().addParam("type", "waste_classify"));
        sysDictions.forEach(sysDiction -> {
            WarnWeight warnWeight = new WarnWeight(hospitalBaseId);
            warnWeight.setWasteClassifyId(sysDiction.getCode());
            warnWeightMapper.insert(warnWeight);
        });
    }

    private void removeUser(String mobile) {
        SysUser sysUser = sysUserMapper.getUserByLoginName(mobile);
        String staffId = sysUserHospitalMapper.getIdByUserId(sysUser.getId());
        sysUserMapper.deleteByPrimaryKey(sysUser.getId());
        sysUserHospitalMapper.deleteByPrimaryKey(staffId);
        sysRoleMapper.removeUser(sysUser.getId());
    }

    private String generateCode() {
        int order = 1;
        String lastest = hospitalBaseMapper.getLastest();
        if (!StringUtil.isNullOrEmpty(lastest)) {
            order = Integer.parseInt(lastest) + 1;
        }
        return String.format("%04d", order);
    }


}